﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using io = System.IO;

namespace MetaSharp.Transformation
{
    public class TextStream : IStream, IComparable<IStream>
    {
        private StreamReader stream;
        private long index;
        private char current;
        private bool empty;
        private TextStream next;

        public TextStream(StreamReader stream)
        {
            this.Initialize(-1, stream);
        }

        private TextStream(long index, StreamReader stream)
        {
            this.Initialize(index, stream);
        }

        private void Initialize(long index, StreamReader stream)
        { 
            this.index = index;
            this.stream = stream;
            if (this.index > -1)
                current = (char)stream.Read();

            empty = stream.EndOfStream;
        }

        public object Current
        {
            get
            {
                if (this.index == -1)
                    throw new InvalidOperationException();
                return this.current;
            }
        }

        public long Index
        {
            get { return this.index + 1; }
        }

        public bool IsEmpty
        {
            get { return this.empty; }
        }

        public IStream Into()
        {
            throw new NotSupportedException();
        }

        public IStream Next()
        {
            if (this.next == null)
            {
                lock (this.stream)
                {
                    if (this.next == null)
                    {
                        this.next = new TextStream(this.index + 1, this.stream);
                    }
                }
            }

            return this.next;
        }

        public static bool operator <(TextStream s1, TextStream s2)
        {
            return op_Spaceship(s1, s2) < 0;
        }

        public static bool operator <=(TextStream s1, TextStream s2)
        {
            return op_Spaceship(s1, s2) < 1;
        }

        public static bool operator >(TextStream s1, TextStream s2)
        {
            return op_Spaceship(s1, s2) > 0;
        }

        public static bool operator >=(TextStream s1, TextStream s2)
        {
            return op_Spaceship(s1, s2) > -1;
        }

        private static int op_Spaceship(TextStream s1, TextStream s2)
        {
            return ((IComparable<IStream>)s1).CompareTo(s2);
        }

        int IComparable<IStream>.CompareTo(IStream other)
        {
            var stream = (TextStream)other;
            return this.index.CompareTo(stream.index);
        }

        int IComparable.CompareTo(object obj)
        {
            return ((IComparable<IStream>)this).CompareTo((IStream)obj);
        }
    }
}
